/*
 * AT24C02.c
 *
 *  Created on: Mar 1, 2024
 *      Author: Administrator
 */
#include "AT24C02.h"
#include "main.h"
void DAT_IN()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin=DAT_Pin;
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull=GPIO_PULLUP;
	GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void DAT_OUT()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin=DAT_Pin;
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull=GPIO_PULLUP;
	GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void IIC_Start()
{
	DAT_OUT();
	DAT_WRITE(1);
	CLK(1);
	delay_us(5);
	DAT_WRITE(0);
	delay_us(5);
	CLK(0);
}
void IIC_End()
{
	DAT_OUT();
	CLK(0);
	DAT_WRITE(0);
	delay_us(5);
	CLK(1);
	delay_us(5);
	DAT_WRITE(1);
}
void IIC_SendAck()
{
	CLK(0);
	DAT_OUT();
	DAT_WRITE(0);
	delay_us(5);
	CLK(1);
	delay_us(5);
	CLK(0);
}
void IIC_SendNoAck()
{
	CLK(0);
	DAT_OUT();
	DAT_WRITE(1);
	delay_us(5);
	CLK(1);
	delay_us(5);
	CLK(0);
}
uint8_t IIC_WaitAck()
{
	uint8_t temp=0;
	DAT_IN();
	CLK(1);
	delay_us(5);
	while(DAT_READ())
	{
		temp++;
		if(temp>250)
		{
			IIC_End();
			return NOACK;
		}
	}
	CLK(0);
	return ACK;
}
void IIC_SendByte(uint8_t data)
{
	DAT_OUT();
	CLK(0);
	for(uint8_t i;i<8;i++)
	{
		DAT_WRITE((data&0x80)>>7);
		data<<=1;
		CLK(1);
		delay_us(5);
		CLK(0);
		delay_us(5);
	}
	CLK(0);
}
uint8_t IIC_ReceiveByte(uint8_t ackflag)
{
	uint8_t rxdata=0;
	DAT_IN();
	for(uint8_t i;i<8;i++)
	{
		rxdata<<=1;
		CLK(1);
		delay_us(5);
		if(DAT_READ())
		{
			rxdata|=0x1;
		}
		CLK(0);
		delay_us(5);
	}
	if(ackflag==1)
	{
		IIC_SendAck();
	}
	else {
		IIC_SendNoAck();
	}
	CLK(0);
	return rxdata;
}
void AT24C02_SendByte(uint16_t addr,uint8_t data)
{
	IIC_Start();
	IIC_SendByte(0xA0+((addr/256)<<1));
	if(IIC_WaitAck()!=ACK)
	{
		IIC_End();
		return;
	}
	IIC_SendByte(addr&0xff);
		if(IIC_WaitAck()!=ACK)
		{
			IIC_End();
			return;
		}
	IIC_SendByte(data);
	if(IIC_WaitAck()!=ACK)
	{
		IIC_End();
		return;
	}
	IIC_End();
}
uint8_t AT24C02_ReceiveByte(uint16_t addr)
{
	uint8_t data=0;
	IIC_SendByte(0xA0+(addr/256)<<1);
	if(IIC_WaitAck()!=ACK)
	{
		IIC_End();
		return;
	}
	IIC_SendByte(addr&0xff);
	if(IIC_WaitAck()!=ACK)
	{
		IIC_End();
		return;
	}
	IIC_Start();
	IIC_SendByte(0xA1);
	if(IIC_WaitAck()!=ACK)
	{
		IIC_End();
		return;
	}
	data=IIC_ReceiveByte(0);
	IIC_End();
	return data;
}
